package com.zj.weather.bgviews;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;

import java.util.ArrayList;
import java.util.List;

import com.zj.weather.base.BaseHolder;
import com.zj.weather.base.BaseWeatherBgView;
import com.zj.weather.base.HoldersInfo;
import com.zj.weather.utils.DebugUtils;
import com.zj.weather.utils.DisplayUtils;
import com.zj.weather.utils.StaticValue;

import static com.zj.weather.utils.RandomUtils.getRandom;

/**
 * Created by zhaojie on 2017/9/14.
 */
public class RainDrawer extends BaseWeatherBgView {

    private static final int maxCount = 650;

    public RainDrawer(Context context) {
        super(context);
    }

    @Override
    protected List<HoldersInfo> getHolders() {
        List<HoldersInfo> infos = new ArrayList<>();
        infos.add(new HoldersInfo(maxCount) {
            @Override
            public RainHolder getHolderType(int position) {
                return new RainHolder(width, height, position, 1600);
            }
        });
        return infos;
    }

    public static class RainHolder extends BaseHolder {

        private final float maxRainWidth = 0.55f;
        private final float minRainWidth = 0.25f;
        private final float rainSpeed;
        private final float degree = 8f;

        private float rainDefaultHeight = 60.0f;
        private float rainMinHeight;
        private float rainX;
        private Paint rainPaint;

        public RainHolder(float x, float y, int position, float rainSpeed) {
            super(x, y, position);
            this.rainSpeed = rainSpeed;
        }

        @Override
        public void initData(Context context) {
            rainPaint = new Paint();
            rainPaint.setAntiAlias(true);
            rainPaint.setStyle(Style.FILL);
            rainMinHeight = rainDefaultHeight * 1f / 5f;
            setRandomParams(context);
            final float maxTime = canvasHeight / this.v;
            this.curTime = getRandom(0, maxTime);
        }

        @Override
        public void updateFrame(Context context, Canvas canvas, float changedAlpha) {
            float degreeOffset = getRandom(0, degree) * offsetX;
            int drawAlpha = (int) (rainAlpha * changedAlpha);
            curTime += 0.03f;
            float curY = curTime * this.v;
            float curX = (rainX += degreeOffset);
            rainPaint.setColor(Color.argb(drawAlpha, 0xff, 0xff, 0xff));
            rainPaint.setStrokeWidth(rainWidth);
            canvas.drawLine(curX, curY - rainHeight, curX + degreeOffset, curY, rainPaint);
            if ((curY - this.rainHeight) > this.canvasHeight) {
                onFrameEnd();
                setRandomParams(context);
            }
        }

        private void onFrameEnd() {
            offsetX = getRandom(-0.15f, 0.15f);
            this.curTime = 0f;
        }

        private float rainWidth;
        private float rainHeight;
        private float curTime;
        private float rainAlpha;
        private float v;
        private float offsetX;

        private void setRandomParams(Context context) {
            this.rainX = getRandom(0, canvasWidth);
            float rainWidth = (maxRainWidth - minRainWidth);
            float width = getRandom(0.0f, 1.0f) * rainWidth;
            float rainRatio = width / rainWidth;
            float height = (1.0f - rainRatio) * (rainDefaultHeight - rainMinHeight) + rainMinHeight;
            float[] f = getCurAlpha();
            float maxAlpha = f[1] * 255f;
            float minAlpha = f[0] * 255f;
            this.rainAlpha = Math.max(minAlpha, maxAlpha * rainRatio);
            this.v = rainSpeed * (0.75f + 0.25f * rainRatio);
            this.rainWidth = DisplayUtils.dip2px(context, width + minRainWidth);
            this.rainHeight = DisplayUtils.dip2px(context, height);
        }
    }

    private static float[] getCurAlpha() {
        float[] alpha = new float[2];
        if (StaticValue.isDay()) {
            alpha[0] = 0.081f;
            alpha[1] = 0.153f;
        } else {
            alpha[0] = 0.04f;
            alpha[1] = 0.163f;
        }
        return alpha;
    }
}